import { ViewController } from '../core/ViewController';
import { Action } from '../core/Action';
import { ListView } from '../core/ListView';
import { DetailView } from '../core/DetailView';
import { Application } from '../core/Application';
import { ModelStore } from '../model/ModelStore';

/**
 * CommonViewController - Provides basic actions like New, Edit, Delete, Save, Cancel
 */
export class CommonViewController extends ViewController {
  private _newAction: Action;
  private _editAction: Action;
  private _deleteAction: Action;
  private _saveAction: Action;
  private _cancelAction: Action;
  private _refreshAction: Action;

  /**
   * Create a new CommonViewController
   */
  constructor() {
    super('CommonViewController');
    
    // Create actions
    this._newAction = new Action('New', 'New');
    this._editAction = new Action('Edit', 'Edit');
    this._deleteAction = new Action('Delete', 'Delete');
    this._saveAction = new Action('Save', 'Save');
    this._cancelAction = new Action('Cancel', 'Cancel');
    this._refreshAction = new Action('Refresh', 'Refresh');
    
    // Set confirmation for delete
    this._deleteAction.confirmationMessage = 'Are you sure you want to delete this item?';
    
    // Register actions
    this.registerAction(this._newAction);
    this.registerAction(this._editAction);
    this.registerAction(this._deleteAction);
    this.registerAction(this._saveAction);
    this.registerAction(this._cancelAction);
    this.registerAction(this._refreshAction);
    
    // Set action handlers
    this._newAction.setExecuteHandler(() => this.onNew());
    this._editAction.setExecuteHandler(() => this.onEdit());
    this._deleteAction.setExecuteHandler(() => this.onDelete());
    this._saveAction.setExecuteHandler(() => this.onSave());
    this._cancelAction.setExecuteHandler(() => this.onCancel());
    this._refreshAction.setExecuteHandler(() => this.onRefresh());
  }

  /**
   * Called when the view is set
   */
  protected onViewSet(): void {
    this.updateActionVisibility();
  }  /**
   * Update action visibility based on view type
   */
  private updateActionVisibility(): void {
    const view = this.view;
    
    console.log(`CommonViewController: updateActionVisibility for view ${view?.constructor.name}`);
    
    // First hide all actions
    this._newAction.visible = false;
    this._editAction.visible = false;
    this._deleteAction.visible = false;
    this._saveAction.visible = false;
    this._cancelAction.visible = false;
    this._refreshAction.visible = false;

    // Then show relevant actions based on view type
    if (view instanceof ListView) {
      console.log('Setting up actions for ListView');
      
      // In ListView, show New, Edit, Delete, and Refresh
      this._newAction.visible = true;
      this._editAction.visible = true;
      this._deleteAction.visible = true;
      this._refreshAction.visible = true;
      
      // Save and Cancel should never be visible in ListView
      this._saveAction.visible = false;
      this._cancelAction.visible = false;

      // Enable/disable Edit and Delete based on selection
      const hasSelection = this.getSelectedItem() !== null;
      console.log('ListView selection state:', hasSelection);
      this._editAction.enabled = hasSelection;
      this._deleteAction.enabled = hasSelection;
    } else if (view instanceof DetailView) {
      console.log('Setting up actions for DetailView');
      
      // In DetailView, show Save and Cancel only
      this._saveAction.visible = true;
      this._cancelAction.visible = true;
      
      // ListView actions should never be visible in DetailView
      this._newAction.visible = false;
      this._editAction.visible = false;
      this._deleteAction.visible = false;
      this._refreshAction.visible = false;

      // Enable Save only if there are no validation errors
      this._saveAction.enabled = !view.hasValidationErrors;
    }

    // Force action state update
    console.log('Updating action states');
    this._newAction.updateState();
    this._editAction.updateState();
    this._deleteAction.updateState();
    this._saveAction.updateState();
    this._cancelAction.updateState();
    this._refreshAction.updateState();
    
    console.log('Action visibility updated:',
      { 
        new: `${this._newAction.visible}/${this._newAction.enabled}`,
        edit: `${this._editAction.visible}/${this._editAction.enabled}`,
        delete: `${this._deleteAction.visible}/${this._deleteAction.enabled}`,
        save: `${this._saveAction.visible}/${this._saveAction.enabled}`,
        cancel: `${this._cancelAction.visible}/${this._cancelAction.enabled}`,
        refresh: `${this._refreshAction.visible}/${this._refreshAction.enabled}`
      }
    );
  }/**
   * Handle New action
   */
  private onNew(): void {
    const view = this.view;
    
    if (view instanceof ListView) {
      const app = Application.getInstance();
      const window = app.activeWindow;
      const dataSource = view.dataSource;
      
      if (window) {
        // Get the business object definition
        const modelStore = ModelStore.getInstance();
        const boName = dataSource ? dataSource.objectTypeName : 'Object';
        const boDefinition = modelStore.getBusinessObjectByName(boName);
        
        // Create a consistent ID for new detail view
        const detailViewId = `${boName}_detail_new`;
        
        // Create a detail view for the new object
        const detailView = new DetailView(detailViewId, `New ${boName}`);
        
        // Set an empty object
        detailView.setObject({ _type: boName });
        
        // Set the data source from the list view
        if (dataSource) {
          detailView.dataSource = dataSource;
        }
        
        // Add property editors based on the business object definition
        if (boDefinition) {
          for (const prop of boDefinition.properties) {
            if (prop.isVisible !== false) {
              detailView.addPropertyEditorByInfo(
                prop.name, 
                prop.displayName || prop.name, 
                prop.type,
                prop.isReadOnly || false,
                prop.isRequired || false
              );
            }
          }
        }
        
        // Add this controller to the detail view
        detailView.addController(this);
        
        // Navigate to the detail view
        window.navigate(detailView);
        
        console.log('Created new detail view:', detailView);
      }
    }
  }/**
   * Handle Edit action
   */
  private onEdit(): void {
    const view = this.view;
    
    if (view instanceof ListView) {
      // Get the selected item
      const selectedItem = this.getSelectedItem();
      
      if (selectedItem) {
        const app = Application.getInstance();
        const window = app.activeWindow;
        const dataSource = view.dataSource;
        
        if (window) {
          // Get the business object definition
          const modelStore = ModelStore.getInstance();
          const boName = dataSource ? dataSource.objectTypeName : 'Object';
          const boDefinition = modelStore.getBusinessObjectByName(boName);
          
          // Create a consistent ID for this detail view
          const itemId = selectedItem.id || 'new';
          const detailViewId = `${boName}_detail_${itemId}`;
          
          // Create a detail view for the selected object
          const detailView = new DetailView(detailViewId, `Edit ${boName}`);
          
          // Set the selected object
          detailView.setObject({...selectedItem}); // Clone the object to avoid reference issues
          
          // Set the data source from the list view
          if (dataSource) {
            detailView.dataSource = dataSource;
          }
          
          // Add property editors based on the business object definition
          if (boDefinition) {
            for (const prop of boDefinition.properties) {
              if (prop.isVisible !== false) {
                detailView.addPropertyEditorByInfo(
                  prop.name, 
                  prop.displayName || prop.name, 
                  prop.type,
                  prop.isReadOnly || false,
                  prop.isRequired || false
                );
              }
            }
          }
          
          // Add this controller to the detail view
          detailView.addController(this);
          
          // Navigate to the detail view, creating a new frame
          window.navigate(detailView);
          
          console.log('Created edit detail view:', detailView);
        }
      } else {
        alert('Please select an item to edit');
      }
    }
  }

  /**
   * Handle Delete action
   */
  private onDelete(): void {
    const view = this.view;
    
    if (view instanceof ListView) {
      // Get the selected item
      const selectedItem = this.getSelectedItem();
      
      if (selectedItem) {
        // Delete from data source
        const dataSource = view.dataSource;
        
        dataSource.delete(selectedItem.id)
          .then(() => {
            // Refresh the view
            this.onRefresh();
          })
          .catch(error => {
            console.error('Error deleting item:', error);
            alert('Failed to delete item: ' + error.message);
          });
      } else {
        alert('Please select an item to delete');
      }
    }
  }

  /**
   * Handle Save action
   */
  private onSave(): void {
    const view = this.view;
    
    if (view instanceof DetailView) {
      const object = view.currentObject;
      
      if (object) {
        // Determine if this is a new or existing object
        if (object.id) {
          // Update existing object
          const dataSource = this.getDataSourceForObjectType(object._type);
          
          if (dataSource) {
            dataSource.update(object.id, object)
              .then(() => {
                alert('Object saved successfully');
                this.closeDetailView();
              })
              .catch((error: any) => {
                console.error('Error updating object:', error);
                alert('Failed to update object: ' + error.message);
              });
          }
        } else {
          // Create new object
          const dataSource = this.getDataSourceForObjectType(object._type);
          
          if (dataSource) {
            dataSource.create(object)
              .then(() => {
                alert('Object created successfully');
                this.closeDetailView();
              })
              .catch((error: any) => {
                console.error('Error creating object:', error);
                alert('Failed to create object: ' + error.message);
              });
          }
        }
      }
    }
  }

  /**
   * Handle Cancel action
   */
  private onCancel(): void {
    this.closeDetailView();
  }

  /**
   * Handle Refresh action
   */
  private onRefresh(): void {
    const view = this.view;
    
    if (view instanceof ListView) {
      const dataSource = view.dataSource;
      
      dataSource.load()
        .catch(error => {
          console.error('Error refreshing data:', error);
          alert('Failed to refresh data: ' + error.message);
        });
    }
  }

  /**
   * Get the selected item in a ListView
   */
  private getSelectedItem(): any {
    const view = this.view;
    if (view instanceof ListView) {
      return view.selectedItem;
    }
    return null;
  }
  /**
   * Get a DataSource for an object type
   */
  private getDataSourceForObjectType(objectType: string): any {
    // Get DataService to find appropriate DataSource
    if (!objectType) return null;
    
    try {
      const DataService = require('../services/DataService').DataService;
      const dataService = DataService.getInstance();
      return dataService.getDataSource(objectType);
    } catch (error) {
      console.error('Error getting DataSource for object type:', objectType, error);
      return null;
    }
  }  /**
   * Close the current detail view and return to the previous view
   */
  private closeDetailView(): void {
    const app = Application.getInstance();
    const window = app.activeWindow;
    
    if (window && window.activeFrame && window.activeFrame.view instanceof DetailView) {
      // Remember the current view's related list view if it exists
      const currentDetailView = window.activeFrame.view as DetailView;
      const currentObjectType = currentDetailView.currentObject?._type;
      
      // Find the best ListView to return to (one that matches the object type of this detail view)
      let bestListView = window.frames.find(f => 
        f.view instanceof ListView && 
        f.view.dataSource && 
        f.view.dataSource.objectTypeName === currentObjectType
      );
      
      // If no matching ListView found, just find any ListView
      if (!bestListView) {
        bestListView = window.frames.find(f => f.view instanceof ListView);
      }
      
      // Close the current detail view frame
      console.log('Closing detail view frame:', window.activeFrame.id);
      window.closeFrame(window.activeFrame);
      
      // If we found a ListView to return to, set it as active
      if (bestListView) {
        console.log('Activating list view frame:', bestListView.id);
        window.setActiveFrame(bestListView);
        
        // Force update action visibility for the ListView
        if (bestListView.view) {
          this.setView(bestListView.view);
          
          // If the ListView has a selection, make sure it's reflected in the UI
          if (bestListView.view instanceof ListView && bestListView.view.selectedItem) {
            console.log('ListView has selected item:', bestListView.view.selectedItem);
            this.updateActionVisibility();
          }
        }
      }
    }
  }
}
